import {
  Injectable,
  Logger,
  NestInterceptor,
  ExecutionContext,
  CallHandler,
  HttpException,
} from '@nestjs/common';
import { Observable } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
/**
 * 请求拦截器
 * 1.记录调用日志
 */
@Injectable()
export class DataInterceptor extends Logger implements NestInterceptor {
  constructor() {
    super();
  }

  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    // console.log(context.getArgs())
    // 请求参数
    const time = Date.now();
    const logName = context.getClass().name + '/' + context.getHandler().name;
    // const getRequest = context.switchToHttp().getRequest();
    // getRequest.body = JSON.parse(getRequest.body.toString('utf8'))

    // 控制台显示信息，（请求）
    this.log(
      'start calling at: ' +
        new Date(time).toLocaleTimeString() +
        '.' +
        new Date(time).getMilliseconds(),
      logName,
    );

    return next.handle().pipe(
      map((data) => {
        // 记录日志
        if (process.env.NODE_ENV !== 'test') {
        }
        this.log(
          'called consuming time: ' +
            (new Date().getTime() - new Date(time).getTime()) +
            'ms',
          logName,
        );
        return data;
      }),
      catchError((err: any) => {
        console.log(err);
        // console.log('data interceptor:', err['response']['message'][0].constraints)
        let code = 3001;
        let message = err['response']['message'];
        // console.log(message)
        if (message instanceof Array && message.length > 0) {
          let oriMessage = '';
          if (message[0].constraints.hasOwnProperty('isInt')) {
            oriMessage = message[0].constraints.isInt;
          } else if (message[0].constraints.hasOwnProperty('IsArray')) {
            oriMessage = message[0].constraints.IsArray;
          } else if (message[0].constraints.hasOwnProperty('isEmail')) {
            oriMessage = message[0].constraints.isEmail;
          } else if (message[0].constraints.hasOwnProperty('isString')) {
            oriMessage = message[0].constraints.isString;
          } else if (message[0].constraints.hasOwnProperty('IsDate')) {
            oriMessage = message[0].constraints.IsDate;
          } else if (message[0].constraints.hasOwnProperty('IsBoolean')) {
            oriMessage = message[0].constraints.IsBoolean;
          } else if (message[0].constraints.hasOwnProperty('isLength')) {
            oriMessage = message[0].constraints.isLength;
          } else if (message[0].constraints.hasOwnProperty('isNumber')) {
            oriMessage = message[0].constraints.isNumber;
          } else if (message[0].constraints.hasOwnProperty('min')) {
            oriMessage = message[0].constraints.min;
          } else if (message[0].constraints.hasOwnProperty('max')) {
            oriMessage = message[0].constraints.max;
          }
          if (oriMessage.includes('message')) {
            message = JSON.parse(oriMessage).message;
            code = JSON.parse(oriMessage).code;
          } else {
            message = oriMessage;
          }
        } else {
          if (err.message && err.message.code) {
            code = err.message.code;
          }
          message = err.message.message;
        }

        const result = {
          code,
          message,
          data: {},
        };
        this.log(JSON.stringify(result));
        if (process.env.NODE_ENV !== 'test') {
          // 错误信息在控制台中显示
          this.error(err.message, err.stack, logName);
        }
        const res = { code: code || 3001, message, data: '' };
        console.log('data interceptor res', res);
        throw new HttpException(res, 500);
      }),
    );
  }
}
